// 版权归 Epic Games, Inc. 所有。保留所有权利。

#pragma once

#include "CommonTabListWidgetBase.h"

#include "LyraTabListWidgetBase.generated.h"

#define UE_API LYRAGAME_API

class UCommonButtonBase;
class UCommonUserWidget;
class UObject;
class UWidget;
struct FFrame;

/**
 * Lyra 选项卡描述符结构
 */
USTRUCT(BlueprintType)
struct FLyraTabDescriptor
{
	GENERATED_BODY()

public:
	FLyraTabDescriptor()
	: bHidden(false) // 默认不隐藏
	, CreatedTabContentWidget(nullptr) // 默认无创建的内容控件
	{ }

	UPROPERTY(EditAnywhere, BlueprintReadOnly)
	FName TabId; // 选项卡ID

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FText TabText; // 选项卡文本

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FSlateBrush IconBrush; // 图标画刷

	UPROPERTY(EditAnywhere, BlueprintReadOnly)
	bool bHidden; // 是否隐藏

	UPROPERTY(EditAnywhere, BlueprintReadOnly)
	TSubclassOf<UCommonButtonBase> TabButtonType; // 选项卡按钮类型

	//TODO NDarnell - 这应该变成 TSoftClassPtr<>，底层的通用选项卡列表需要能够处理延迟的选项卡内容构造。
	UPROPERTY(EditAnywhere, BlueprintReadOnly)
	TSubclassOf<UCommonUserWidget> TabContentType; // 选项卡内容类型

	UPROPERTY(Transient)
	TObjectPtr<UWidget> CreatedTabContentWidget; // 已创建的选项卡内容控件
};

/**
 * Lyra 选项卡按钮接口
 */
UINTERFACE(BlueprintType)
class ULyraTabButtonInterface : public UInterface
{
	GENERATED_BODY()
};

class ILyraTabButtonInterface
{
	GENERATED_BODY()

public:
	/**
	 * 设置选项卡标签信息
	 * @param TabDescriptor 选项卡描述符
	 */
	UFUNCTION(BlueprintNativeEvent, Category = "Tab Button")
	void SetTabLabelInfo(const FLyraTabDescriptor& TabDescriptor);
};

/**
 * Lyra 选项卡列表控件基类
 */
UCLASS(MinimalAPI, Blueprintable, BlueprintType, Abstract, meta = (DisableNativeTick))
class ULyraTabListWidgetBase : public UCommonTabListWidgetBase
{
	GENERATED_BODY()
	
public:
	/**
	 * 获取预注册的选项卡信息
	 * @param TabNameId 选项卡名称ID
	 * @param OutTabInfo 输出的选项卡信息
	 * @return 是否找到
	 */
	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Tab List")
	UE_API bool GetPreregisteredTabInfo(const FName TabNameId, FLyraTabDescriptor& OutTabInfo);

	/** 辅助方法获取所有预注册的选项卡信息 */
	const TArray<FLyraTabDescriptor>& GetAllPreregisteredTabInfos() { return PreregisteredTabInfoArray; }

	/**
	 * 切换指定选项卡的隐藏状态，只能在关联切换器之前调用
	 * @param TabNameId 选项卡名称ID
	 * @param bHidden 是否隐藏
	 */
	UFUNCTION(BlueprintCallable, Category = "Tab List")
	UE_API void SetTabHiddenState(FName TabNameId, bool bHidden);

	/**
	 * 注册动态选项卡
	 * @param TabDescriptor 选项卡描述符
	 * @return 是否成功
	 */
	UFUNCTION(BlueprintCallable, Category = "Tab List")
	UE_API bool RegisterDynamicTab(const FLyraTabDescriptor& TabDescriptor);

	/**
	 * 检查第一个选项卡是否激活
	 * @return 是否激活
	 */
	UFUNCTION(BlueprintCallable, Category = "Tab List")
	UE_API bool IsFirstTabActive() const;

	/**
	 * 检查最后一个选项卡是否激活
	 * @return 是否激活
	 */
	UFUNCTION(BlueprintCallable, Category = "Tab List")
	UE_API bool IsLastTabActive() const;

	/**
	 * 检查选项卡是否可见
	 * @param TabId 选项卡ID
	 * @return 是否可见
	 */
	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Tab List")
	UE_API bool IsTabVisible(FName TabId);

	/**
	 * 获取可见选项卡数量
	 * @return 可见选项卡数量
	 */
	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Tab List")
	UE_API int32 GetVisibleTabCount();

	/** 新选项卡创建时广播的委托 */
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnTabContentCreated, FName, TabId, UCommonUserWidget*, TabWidget);
	DECLARE_EVENT_TwoParams(ULyraTabListWidgetBase, FOnTabContentCreatedNative, FName /* TabId */, UCommonUserWidget* /* TabWidget */);

	/** 新选项卡创建时广播 */
	UPROPERTY(BlueprintAssignable, Category = "Tab List")
	FOnTabContentCreated OnTabContentCreated; // 选项卡内容创建委托
	FOnTabContentCreatedNative OnTabContentCreatedNative; // 原生选项卡内容创建事件

protected:
	// UUserWidget 接口
	/**
	 * 原生初始化
	 */
	UE_API virtual void NativeOnInitialized() override;

	/**
	 * 原生构造
	 */
	UE_API virtual void NativeConstruct() override;

	/**
	 * 原生析构
	 */
	UE_API virtual void NativeDestruct() override;
	// End UUserWidget

	/**
	 * 处理预链接切换器改变
	 */
	UE_API virtual void HandlePreLinkedSwitcherChanged() override;

	/**
	 * 处理后链接切换器改变
	 */
	UE_API virtual void HandlePostLinkedSwitcherChanged() override;

	/**
	 * 处理选项卡创建
	 * @param TabId 选项卡ID
	 * @param TabButton 选项卡按钮
	 */
	UE_API virtual void HandleTabCreation_Implementation(FName TabId, UCommonButtonBase* TabButton) override;

private:
	/**
	 * 设置选项卡
	 */
	UE_API void SetupTabs();

	UPROPERTY(EditAnywhere, meta=(TitleProperty="TabId"))
	TArray<FLyraTabDescriptor> PreregisteredTabInfoArray; // 预注册选项卡信息数组
	
	/**
	 * 存储运行时注册但尚未创建的选项卡的标签信息。
	 * 元素在创建后会被移除。
	 */
	UPROPERTY()
	TMap<FName, FLyraTabDescriptor> PendingTabLabelInfoMap; // 待处理选项卡标签信息映射
};

#undef UE_API